package droid.pkg.test;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.Display;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;
import android.widget.TextView;

public class TiltBall extends Activity {

	BallView mBallView = null;
	Handler RedrawHandler = new Handler(); //so redraw occurs in main thread
	Timer mTmr = null;
	TimerTask mTsk = null;
	int mScrWidth, mScrHeight;
	android.graphics.PointF mBallPos, mBallSpd;
	final float dt =0.9f;
	public float BOUNCE = 0.99f;
	final float gravity = 9.8f;
	float mAz;
	
	public int RADIUS = 75;
	public int COLOR = 0xFFFF0000;
	
	private final float FRICTION= 0.85f; 
	
	TextView mtext =  null;
	TextView mtext2 =  null;
	TextView mtext3 =  null;
	double x = 0.0, y = 0.0;
	
	
	int flag=-1;
	//color hex is [transparency][red][green][blue]
	private int[] COLORS = {0xff00ccff, 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff0c3707, 0xffcd095d, 0xffe61e09, 0xff480ba1, 0xffaabbcc, 
			0xffbbaccd};
	
	Random r = new Random();
	
	double Tdx;
	double Tdy;

	@Override
	public void onCreate(Bundle savedInstanceState){
		requestWindowFeature(Window.FEATURE_NO_TITLE); //hide title bar
		//set app to full screen and keep screen on 
		getWindow().setFlags(0xFFFFFFFF,
				LayoutParams.FLAG_FULLSCREEN|LayoutParams.FLAG_KEEP_SCREEN_ON);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_tilt_ball);
		//create pointer to main screen
		final FrameLayout mainView = 
				(android.widget.FrameLayout)findViewById(R.id.main_view);
		
		//get screen dimensions
		Display display = getWindowManager().getDefaultDisplay();  
		Point size = new Point();
		display.getSize(size);
		mScrWidth = size.x;  
		mScrHeight = size.y;
		mBallPos = new android.graphics.PointF();
		mBallSpd = new android.graphics.PointF();

		//create variables for ball position and speed
		mBallPos.x = mScrWidth/2; 
		mBallPos.y = mScrHeight/2; 
		mBallSpd.x = 0;
		mBallSpd.y = 0; 

		//create initial ball
		mBallView = new BallView(this, mBallPos.x, mBallPos.y, RADIUS, COLOR);

		mainView.addView(mBallView); //add ball to main screen
		mBallView.invalidate(); //call onDraw in BallView
		
		mtext= new TextView(this);
		mtext2= new TextView(this);
		mtext3 = new TextView(this);
		
		mtext2.setPadding(0, 50, 0, 0);
		mtext3.setPadding(0, 200, 0, 0);
		
		mainView.addView(mtext);
		
		mainView.addView(mtext2);
		mainView.addView(mtext3);
		
		//listener for accelerometer, use anonymous class for simplicity
		((SensorManager)getSystemService(Context.SENSOR_SERVICE)).registerListener(
				new SensorEventListener() {    
					@Override  
					public void onSensorChanged(SensorEvent event) {  
						//set ball speed based on phone tilt (ignore Z axis)
						mBallSpd.x = -event.values[0];
						mBallSpd.y = event.values[1];
						mAz= event.values[2];
						x=-event.values[0];
						y=event.values[1];
						
						//timer event will redraw ball
						mBallSpd.x = Math.signum(mBallSpd.x) * Math.abs(mBallSpd.x) * (1 - FRICTION * Math.abs(mAz) / gravity);
						mBallSpd.y = Math.signum(mBallSpd.y) * Math.abs(mBallSpd.y) * (1 - FRICTION * Math.abs(mAz) / gravity);
						
					}
					@Override  
					public void onAccuracyChanged(Sensor sensor, int accuracy) {} //ignore
				},
				((SensorManager)getSystemService(Context.SENSOR_SERVICE))
				.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0),   
				SensorManager.SENSOR_DELAY_NORMAL);

		//listener for touch event 
		mainView.setOnTouchListener(new android.view.View.OnTouchListener() {
			public boolean onTouch(android.view.View v, android.view.MotionEvent e) {
				//set ball position based on screen touch
				mBallPos.x = e.getX();
				mBallPos.y = e.getY();
				//timer event will redraw ball
				return true;
			}}); 
		
		
	}

	
	
	

	//listener for menu item clicked
	@Override
	public boolean onOptionsItemSelected(MenuItem item) 
	{
		// Handle item selection    
		if (item.getTitle() == "Exit") //user clicked Exit
			finish(); //will call onPause
		else if(item.getTitle() == "Settings");{
			
		}
		return super.onOptionsItemSelected(item);    
	}

	//For state flow see http://developer.android.com/reference/android/app/Activity.html
	@Override
	public void onPause() //app moved to background, stop background threads
	{
		mTmr.cancel(); //kill\release timer (our only background thread)
		mTmr = null;
		mTsk = null;
		super.onPause();
	}

	
	
	@Override
	public void onResume() //app moved to foreground (also occurs at app startup)
	{
		//create timer to move ball to new position
		mTmr = new Timer(); 
		mTsk = new TimerTask() {
			public void run() {
				//if debugging with external device, 
				//  a log cat viewer will be needed on the device
				android.util.Log.d("TiltBall","Timer Hit - " + mBallPos.x + ":" + mBallPos.y);
				
				//move ball based on current speed				
				flag=0;
				
				mBallSpd.x+= x*dt;
				mBallSpd.y+= y*dt;
				
				mBallPos.x += (int)(dt*(mBallSpd.x+0.5*x*dt));
				mBallPos.y += (int)(dt*(mBallSpd.y+0.5*y*dt));
				
				if(mBallPos.x < RADIUS){
					mBallPos.x = RADIUS;
					mBallSpd.x*=-BOUNCE;
//					mBallSpd.x*=-1;
					flag=3;
					mBallView.setColor(COLORS[r.nextInt(COLORS.length-1)]);
				}
				if(mBallPos.y < RADIUS){
					mBallPos.y = RADIUS;
					mBallSpd.y*=-BOUNCE;
//					mBallSpd.y*=-1;
					flag=4;
					mBallView.setColor(COLORS[r.nextInt(COLORS.length-1)]);
				}
				if(mBallPos.x > mScrWidth - RADIUS){
					mBallPos.x = mScrWidth - RADIUS;
					mBallSpd.x*=-BOUNCE;
//					mBallSpd.x*=-1;
					flag=1;
					mBallView.setColor(COLORS[r.nextInt(COLORS.length-1)]);
				}
				if(mBallPos.y > mScrHeight - RADIUS){
					mBallPos.y = mScrHeight - RADIUS;
					mBallSpd.y*=-BOUNCE;
//					mBallSpd.y*=-1;
					mBallView.setColor(COLORS[r.nextInt(COLORS.length-1)]);
				}
				
				
				//update ball class instance
				mBallView.x = mBallPos.x;
				mBallView.y = mBallPos.y;
				//redraw ball. Must run in background thread to prevent thread lock.
				RedrawHandler.post(new Runnable() {
					public void run() {    
						mBallView.invalidate();
						mtext.setText("Timer Hit - [X-pos: " + mBallPos.x + "][Y-pos: " + mBallPos.y+"]");
						mtext3.setTextColor(0xFFFF8400);
						mtext3.setText("z-axis: <"+mAz+">");
						if(flag==0){
							mtext2.setTextColor(Color.MAGENTA);
							mtext2.setText("Pos<x,y>: ("+mBallPos.x+","+mBallPos.y+"); Spd<x,y>: ("+mBallSpd.x+","+mBallSpd.y+")");
						}else if(flag==1){
							mtext2.setTextColor(Color.RED);
							mtext2.setText("Ball x-pos: "+ mBallPos.x+"BOUNCE1");
						}else if(flag==2){
							mtext2.setTextColor(Color.BLUE);
							mtext2.setText("Ball y-pos: "+ mBallPos.y+"BOUNCE2");
						}else if(flag==3){
							mtext2.setTextColor(Color.GREEN);
							mtext2.setText("Ball x-pos: "+ mBallPos.x+"BOUNCE3");
						}else if(flag==4){
							mtext2.setTextColor(Color.YELLOW);
							mtext2.setText("Ball y-pos: "+ mBallPos.y+"BOUNCE4");
						}else{
							mtext2.setTextColor(Color.BLACK);
							mtext2.setText("unsure -- Pos<x,y>: ("+mBallPos.x+","+mBallPos.y+"); Spd<x,y>: ("+mBallSpd.x+","+mBallSpd.y+")");
						}
					}});
			}}; // TimerTask
			mTmr.schedule(mTsk,10,10); //start timer
			super.onResume();
	} // onResume
	
	//listener for config change. 
    //This is called when user tilts phone enough to trigger landscape view
    //we want our app to stay in portrait view, so bypass event 
    @Override 
    public void onConfigurationChanged(Configuration newConfig)
    {
       super.onConfigurationChanged(newConfig);
    }

}
